package com.itheima.health.service.impl;

import com.itheima.health.common.MessageConst;
import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrdersettingDao;
import com.itheima.health.dao.SetMealDao;
import com.itheima.health.dto.OrderDTO;
import com.itheima.health.exception.BusinessRuntimeException;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.service.OrderService;
import com.itheima.health.vo.OrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 预约顶动感业务层实现类
 *
 * @author liuqi
 * @Date 2023/11/20
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    /**
     *  注入会员持久层对象
     */
    @Autowired
    private MemberDao memberDao;

    /**
     *  注入预约设置持久层对象
     */
    @Autowired
    private OrdersettingDao ordersettingDao;

    /**
     *  注入预约订单持久层对象
     */
    @Autowired
    private OrderDao orderDao;

    /**
     *  注入套餐持久层对象
     */
    @Autowired
    private SetMealDao setMealDao;

    /**
     *  注入redis模版对象
     */
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 体检预约
     *
     * @param orderVO 体检信息
     * @return 预约订单信息
     */
    @Transactional
    @Override
    public Order submit(OrderVO orderVO) {
        //  1.从redis中获取验证码
        String key = "ORDER" + "_" + orderVO.getTelephone();
        String code = (String) redisTemplate.opsForValue().get(key);
        // 1.1 判断是否查询到验证码
        if(orderVO.getValidateCode() == null || orderVO.getValidateCode() == ""){
            throw new BusinessRuntimeException(MessageConst.VALIDATECODE_ERROR);
        }
        // 1.2 判断验证码输入是否正确
        if(!orderVO.getValidateCode().equals(code)){
            throw new BusinessRuntimeException(MessageConst.VALIDATECODE_ERROR);
        }
        // 2.判断是否输入预约日期
        if(orderVO.getOrderDate() == null){
            throw new BusinessRuntimeException(MessageConst.ORDERDATE_NOTNULL);
        }
        // 3.判断用户是否是会员
        // 3.1获取用户会员信息
        Member member = this.memberDao.findByIdCard(orderVO.getIdCard());
        // 3.2判断用户信息是否为空
        if(member == null){
            // 复制对象内容
            member = new Member();
            member.setName(orderVO.getName());
            member.setSex(orderVO.getSex());
            member.setIdCard(orderVO.getIdCard());
            member.setPhoneNumber(orderVO.getTelephone());
            member.setRegTime(new Date());
            // 新增会员信息
            memberDao.insert(member);
        }
        // 4.判断用户同一天是否预约重复套餐
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        String orderDate = simpleDateFormat.format(orderVO.getOrderDate());
        // 4.1获取用户预购订单信息
        Integer orderCount = this.memberDao.seleteByCondition(member.getId(),orderDate,orderVO.getSetmealId());
        // 4.2判断会员当天是否预约相同的套餐
        if(orderCount > 0){
            throw new BusinessRuntimeException(MessageConst.HAS_ORDERED);
        }
        // 5.该体检预约是否已经约满
        OrderSetting orderSetting = this.ordersettingDao.seleteByOrderDate(orderDate);
        // 5.1判断当天是否预约满了
        if(orderSetting == null) {
            throw new BusinessRuntimeException(MessageConst.SELECTED_DATE_CANNOT_ORDER);
        }
        // 5.2判断当天是否有预约名额
        if (orderSetting.getNumber() <= orderSetting.getReservations()) {
            throw new BusinessRuntimeException(MessageConst.ORDER_FULL);
        }
        // 6.新增预约订单
        // 6.1封装数据
        Order order = new Order();
        order.setMemberId(member.getId());
        order.setOrderDate(orderVO.getOrderDate());
        order.setOrderType(Order.ORDERTYPE_WEIXIN);
        order.setOrderStatus(Order.ORDERSTATUS_NO);
        order.setSetmealId(orderVO.getSetmealId());
        // 6.2调用dao层方法
        this.orderDao.insert(order);
        // 6.3修改预约设置与预约人数
        this.ordersettingDao.updateReservations(orderSetting.getReservations() + 1,orderSetting.getId());
        return order;
    }

    /**
     * 订单数据展示
     *
     * @param id 订单id
     * @return 订单数据
     */
    @Override
    public OrderDTO findById(Integer id) {
        // 1.获取订单信息
        Order order = this.orderDao.findById(id);
        // 1.1 修改日期类型
        Date date = order.getOrderDate();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String orderDate = simpleDateFormat.format(date);
        // 2.获取会员名称
        String member = this.memberDao.findNameById(order.getMemberId());
        // 3.获取套餐名称
        String setmeal = this.setMealDao.findNameById(order.getSetmealId());
        // 4.封装数据
        OrderDTO orderDTO = new OrderDTO();
        // 预约方式
        orderDTO.setOrderType(order.getOrderType());
        // 会员名称
        orderDTO.setMember(member);
        // 预约日期
        orderDTO.setOrderDate(orderDate);
        // 预约套餐名称
        orderDTO.setSetmeal(setmeal);
        // 返回结果
        return orderDTO;
    }
}
